using System;

using Google.Apps.Provisioning.Authentication;
using Google.Apps.Provisioning.Actions;

namespace Google.Apps.Provisioning
{
    /// <summary>
    /// Manages all interaction with the provisioning subsystem.  Any consumers of this API should
    /// use the this class for all API calls.
    /// Google's documentation for their Provisioning API can be found 
    /// <a href="http://code.google.com/apis/apps-for-your-domain/google_apps_provisioning_api_v1.0_reference.html">here</a>.
    /// </summary>
    public class ProvisioningManager
    {
        private ActionController controller;

        /// <summary>
        /// Creates an instance of the ProvisioningManager with the desired context (Domain, SecurityToken).
        /// In a typical environment only one Domain and SecurityToken will be used, so they are stored for
        /// the lifetime of this class.
        /// </summary>
        /// <param name="domain"></param>
        /// <param name="securityToken"></param>
        public ProvisioningManager( string domain, AuthenticationToken securityToken )
        {
            controller = new ActionController( domain, securityToken );
        }

        /// <summary>
        /// Create a user (hosted email account) using Google's Provisioning API.
        /// </summary>
        /// <param name="userName">The username for the account.  This username must be unique.</param>
        /// <param name="password">Password for the account.</param>
        /// <param name="firstName">The first name of the user.</param>
        /// <param name="lastName">The last name of the user.</param>
        /// <param name="quota">The quota (storage space) allowed for the user's email account, in megabytes.</param>
        public ProvisioningResponse CreateUser( 
            string userName, string password, string firstName, string lastName, int quota )
        {
            GoogleUser user = 
                new GoogleUser( userName, password, firstName, lastName, quota );
            
            CreateUserAction action = 
                new CreateUserAction( user );

            return controller.Execute( action );
        }

        /// <summary>
        /// Permanently delete a user.
        /// </summary>
        /// <param name="userName">The username of the account to delete.</param>
        public ProvisioningResponse DeleteUser( string userName )
        {
            DeleteUserAction action = 
                new DeleteUserAction( userName );

            return controller.Execute( action );
        }

        /// <summary>
        /// Retrieves account information for a user.
        /// </summary>
        /// <param name="userName">The username to retrieve information for.</param>
        /// <param name="user">Out parameter populated with the retrieved information.</param>
        public ProvisioningResponse RetrieveUser( string userName, out GoogleUser user )
        {
            RetrieveUserAction action =
                new RetrieveUserAction( userName );

            ProvisioningResponse response =
                controller.Execute( action );

            user = action.GoogleUser;

            return response;
        }

        /// <summary>
        /// Update a user.  Note that the username cannot be updated.
        /// </summary>
        /// <param name="userName">The username for the account.</param>
        /// <param name="password">Password for the account.</param>
        /// <param name="firstName">The first name of the user.</param>
        /// <param name="lastName">The last name of the user.</param>
        public ProvisioningResponse UpdateUser( 
            string userName, string password, string firstName, string lastName )
        {
            GoogleUser user = 
                new GoogleUser( userName, password, firstName, lastName );
            
            UpdateUserAction action = 
                new UpdateUserAction( user );

            return controller.Execute( action );
        }
    }
}
